package com.elitel.frame.base.controller.accessControl;

import com.elitel.common.core.log.annotation.Log;
import com.elitel.common.core.log.enums.BusinessType;
import com.elitel.common.utils.SpringUtils;
import com.elitel.common.utils.ThreadPoolUtils;
import com.elitel.frame.base.component.RedisCacheComponent;
import com.elitel.frame.base.service.AcStationPushRecordService;
import com.elitel.frame.base.service.ApplicationServiceAccessConfigService;
import com.elitel.frame.base.service.CfgExtsqlService;
import com.elitel.frame.base.service.SysPrjServiceService;
import com.elitel.frame.business.service.AcFilterStationPushService;
import com.elitel.frame.main.entity.*;
import com.elitel.frame.main.entity.constant.DictionaryConstant;
import com.elitel.frame.main.entity.constant.ServiceTypeConstant;
import com.elitel.frame.main.entity.dto.AcAppServiceRelationDTO;
import com.elitel.frame.main.entity.vo.AcStationPushRecordVO;
import com.elitel.frame.main.entity.vo.JsonResult;
import com.elitel.frame.task.Server2CacheScheduler;
import com.elitel.frame.task.SyncServiceInterfaceConfigScheduler;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 访问控制-应用和服务访问配置控制器
 *
 * @author hi_bj
 */
@Controller
@RequestMapping("/accesscontrol/appserviceaccessconfig")
public class ApplicationServiceAccessConfigController {

    @Autowired
    ApplicationServiceAccessConfigService applicationServiceAccessConfigService;

    @Autowired
    private AcFilterStationPushService acFilterStationPushService;

    @Autowired
    private SysPrjServiceService sysPrjServiceService;

    @Autowired
    private RedisCacheComponent redisCacheComponent;

    @Autowired
    private CfgExtsqlService cfgExtsqlService;

    @Autowired
    private AcStationPushRecordService acStationPushRecordService;

    /**
     * 获取数据列表
     *
     * @param acAppServiceRelation
     * @return JsonResult
     */
    @RequestMapping("/getDataList")
    @ResponseBody
    public Object getDataList(AcAppServiceRelation acAppServiceRelation) {
        JsonResult jr = new JsonResult();
        jr.setData(applicationServiceAccessConfigService.getDataList(acAppServiceRelation));
        jr.setSuccess(true);
        return jr;
    }

    @RequestMapping("/save")
    @ResponseBody
    @Log(title = "应用调用方信息保存", businessType = BusinessType.UPDATE)
    public Object save(@RequestBody AcAppServiceRelationDTO dto) {
        JsonResult jr = new JsonResult();
        jr.setData(applicationServiceAccessConfigService.save(dto));
        ThreadPoolUtils.execute(() -> {
            // 异步更新缓存
            try {
                SpringUtils.getBean(SyncServiceInterfaceConfigScheduler.class).syncData();
                SpringUtils.getBean(Server2CacheScheduler.class).saveServerInfo2Cache();
            } catch (Exception e) {
            }

        });
        jr.setSuccess(true);
        return jr;
    }


    @RequestMapping("/getInsertStationParams")
    @ResponseBody
    public Object getInsertStationParams(@RequestBody List<AcAppServiceRelation> acAppServiceRelation) {
        JsonResult jr = new JsonResult();
        jr.setData(applicationServiceAccessConfigService.getInsertStationParams(acAppServiceRelation));
        jr.setSuccess(true);
        return jr;
    }


    @RequestMapping("/insertStation")
    @ResponseBody
    public Object insertStation(@RequestParam("serviceId") String serviceId,
                                @RequestBody List<AcFilterStation> acFilterStations) {
        JsonResult jr = new JsonResult();
        try {
            String appCodes = acFilterStations.stream().map(AcFilterStation::getAppCode).filter(StringUtils::isNotEmpty).distinct().collect(Collectors.joining(","));
            SysPrjservice projectConfigByGuid = sysPrjServiceService.getProjectConfigByGuid(serviceId);
            String dbKey = "";
            String servicetype = projectConfigByGuid.getServicetype();
            switch (servicetype) {
                case ServiceTypeConstant.SINGLE_TABLE_SERVER:
                    CfgExtend cfgExtend = redisCacheComponent.cfgExtendRedisCache(projectConfigByGuid.getServicecode());
                    dbKey = cfgExtend.getDbKey();
                    break;
                case ServiceTypeConstant.EXECUTE_SQL_SERVER:
                    CfgExtsql cfgExtsql = cfgExtsqlService.selectCfgSqlByPrimary(projectConfigByGuid.getServicecode());
                    dbKey = cfgExtsql.getDtDbKey();
                    break;
                default:
            }
            CfgDb cfgDB = redisCacheComponent.cfgDBRedisCache(dbKey);
            int i = acFilterStationPushService.save(cfgDB, projectConfigByGuid.getServicecode(), appCodes, acFilterStations);
            jr.setData(i);
            jr.setSuccess(i > 0);
        } catch (Exception e) {
            e.printStackTrace();
            jr.setSuccess(false);
            jr.setMsg("同步分组关联测站数据失败");
        }
        return jr;
    }


    @RequestMapping("/pushStation")
    @ResponseBody
    public Object pushStation() {
        JsonResult jr = new JsonResult();
        try {
            List<AcStationPushRecordVO> datas = acStationPushRecordService.getPushData();
            if (CollectionUtils.isEmpty(datas)) {
                return jr;
            }

            ArrayList<AcStationPushRecord> list = new ArrayList<>();
            // 这个时间复杂度有点高啊
            for (AcStationPushRecordVO data : datas) {
                AcStationPushRecord record = new AcStationPushRecord();
                record.setPushRecordId(data.getPushRecordId());
                List<AcStationPushRecordVO.PushData> pushDataList = data.getPushDataList();
                try {
                    for (AcStationPushRecordVO.PushData pushDatum : pushDataList) {
                        acFilterStationPushService.save(pushDatum.getCfgdb(), pushDatum.getServiceCode(), pushDatum.getAppCode(), pushDatum.getAcFilterStationList());
                    }
                    record.setStatus(DictionaryConstant.YES);
                    record.setErrorMsg("");
                } catch (Exception e) {
                    e.printStackTrace();
                    record.setErrorMsg(e.getMessage());
                    record.setStatus(DictionaryConstant.NO);
                }
                list.add(record);
            }
            acStationPushRecordService.updateList(list);
            jr.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            jr.setSuccess(false);
        }
        return jr;
    }

}
